<?php
/**
 * Elgg groups plugin
 *
 * @package ElggGroups
 * Modifies
 *  TODO: Toan Nguyen
 *    define grouptype
 *    edit create and edit group
 *        register action groups/editgroup
 *        change form from edit to editgroup
 *        remove some default fields in groups_fields_setup such as description and interests
 *    review
 */
// Toan Nguyen
// define grouptype
define('NORMAL_GROUP', 1);
define('SUBJECT_GROUP', 2);
define('PROJECT_GROUP', 3);
elgg_register_event_handler('init', 'system', 'groups_init');

// Ensure this runs after other plugins
elgg_register_event_handler('init', 'system', 'groups_fields_setup', 10000);

/**
 * Initialize the groups plugin.
 */
function groups_init()
{

    elgg_register_library('elgg:groups', elgg_get_plugins_path() . 'groups/lib/groups.php');

    // register group entities for search
    elgg_register_entity_type('group', '');

    // Set up the menu
    $item = new ElggMenuItem('groups', elgg_echo('groups'), 'groups/all');
    elgg_register_menu_item('site', $item);

    // Set up the menu Mon hoc
    $user = elgg_get_logged_in_user_entity();
    if ($user->usertype == "Teacher") {

        elgg_register_menu_item('topbar', array(
            'name' => 'teacher_subjects',
            'href' => 'submana/subjects/' . $user->username,
            'text' => "Môn học phụ trách",
            'priority' => 2000,
            'link_class' => '',
        ));

        elgg_register_menu_item('topbar', array(
            'name' => 'teacher_subjects_project',
            'href' => 'groups/all?filter=project_teacher',
            'text' => "Các nhóm đang hướng dẫn dề tài",
            'priority' => 2001,
            'link_class' => '',
        ));

    }

    // Register a page handler, so we can have nice URLs
    elgg_register_page_handler('groups', 'groups_page_handler');

    // Register URL handlers for groups
    elgg_register_entity_url_handler('group', 'all', 'groups_url');
    elgg_register_plugin_hook_handler('entity:icon:url', 'group', 'groups_icon_url_override');

    // Register an icon handler for groups
    elgg_register_page_handler('groupicon', 'groups_icon_handler');

    // Register some actions
    $action_base = elgg_get_plugins_path() . 'groups/actions/groups';
    elgg_register_action("groups/edit", "$action_base/edit.php");
    elgg_register_action("groups/delete", "$action_base/delete.php");
    elgg_register_action("groups/featured", "$action_base/featured.php", 'admin');

    // TODO: Toan Nguyen
    // Custom create and edit group form
    elgg_register_action("groups/editgroup", "$action_base/editgroup.php");

    // TODO: Kha
    // Register the acrion 'requestsvnrepo'
    elgg_register_action("groups/requestsvnrepo", "$action_base/requestsvnrepo.php");
    elgg_register_action("groups/approvesvn", "$action_base/approvesvn.php");

    // TODO: Toan
    // Teacher review
    elgg_register_action("groups/review", "$action_base/review.php");
    elgg_register_action("groups/mark", "$action_base/mark.php");

    $action_base .= '/membership';
    elgg_register_action("groups/invite", "$action_base/invite.php");
    elgg_register_action("groups/join", "$action_base/join.php");
    elgg_register_action("groups/leave", "$action_base/leave.php");
    elgg_register_action("groups/remove", "$action_base/remove.php");
    elgg_register_action("groups/killrequest", "$action_base/delete_request.php");
    elgg_register_action("groups/killinvitation", "$action_base/delete_invite.php");
    elgg_register_action("groups/addtogroup", "$action_base/add.php");

    // Add some widgets
    elgg_register_widget_type('a_users_groups', elgg_echo('groups:widget:membership'), elgg_echo('groups:widgets:description'));

    // add group activity tool option
    add_group_tool_option('activity', elgg_echo('groups:enableactivity'), true);
    elgg_extend_view('groups/tool_latest', 'groups/profile/activity_module');

    // add link to owner block
    elgg_register_plugin_hook_handler('register', 'menu:owner_block', 'groups_activity_owner_block_menu');


    // group entity menu
    elgg_register_plugin_hook_handler('register', 'menu:entity', 'groups_entity_menu_setup');

    // group user hover menu
    elgg_register_plugin_hook_handler('register', 'menu:user_hover', 'groups_user_entity_menu_setup');

    // delete and edit annotations for topic replies
    elgg_register_plugin_hook_handler('register', 'menu:annotation', 'groups_annotation_menu_setup');

    //extend some views
    elgg_extend_view('css/elgg', 'groups/css');
    elgg_extend_view('js/elgg', 'groups/js');

    // Access permissions
    elgg_register_plugin_hook_handler('access:collections:write', 'all', 'groups_write_acl_plugin_hook');
    //elgg_register_plugin_hook_handler('access:collections:read', 'all', 'groups_read_acl_plugin_hook');

    // Register profile menu hook
    elgg_register_plugin_hook_handler('profile_menu', 'profile', 'forum_profile_menu');
    elgg_register_plugin_hook_handler('profile_menu', 'profile', 'activity_profile_menu');

    // allow ecml in discussion and profiles
    elgg_register_plugin_hook_handler('get_views', 'ecml', 'groups_ecml_views_hook');
    elgg_register_plugin_hook_handler('get_views', 'ecml', 'groupprofile_ecml_views_hook');

    // Register a handler for create groups
    elgg_register_event_handler('create', 'group', 'groups_create_event_listener');

    // Register a handler for delete groups
    elgg_register_event_handler('delete', 'group', 'groups_delete_event_listener');

    elgg_register_event_handler('join', 'group', 'groups_user_join_event_listener');
    elgg_register_event_handler('leave', 'group', 'groups_user_leave_event_listener');
    elgg_register_event_handler('pagesetup', 'system', 'groups_setup_sidebar_menus');

    elgg_register_plugin_hook_handler('access:collections:add_user', 'collection', 'groups_access_collection_override');

    elgg_register_event_handler('upgrade', 'system', 'groups_run_upgrades');
}

/**
 * This function loads a set of default fields into the profile, then triggers
 * a hook letting other plugins to edit add and delete fields.
 *
 * Note: This is a system:init event triggered function and is run at a super
 * low priority to guarantee that it is called after all other plugins have
 * initialized.
 */
function groups_fields_setup()
{

    $profile_defaults = array(
        'description' => 'longtext',
        'briefdescription' => 'plaintext',
        'interests' => 'tags',
        'website' => 'url',
    );

    $profile_defaults = elgg_trigger_plugin_hook('profile:fields', 'group', NULL, $profile_defaults);

    elgg_set_config('group', $profile_defaults);

    // register any tag metadata names
    foreach ($profile_defaults as $name => $type) {
        if ($type == 'tags') {
            elgg_register_tag_metadata_name($name);

            // only shows up in search but why not just set this in en.php as doing it here
            // means you cannot override it in a plugin
            add_translation(get_current_language(), array("tag_names:$name" => elgg_echo("groups:$name")));
        }
    }
}

/**
 * Configure the groups sidebar menu. Triggered on page setup
 *
 */
function groups_setup_sidebar_menus()
{

    // Get the page owner entity
    $page_owner = elgg_get_page_owner_entity();

    if (elgg_in_context('group_profile')) {
        if (elgg_is_logged_in() && $page_owner->canEdit() && !$page_owner->isPublicMembership()) {
            $url = elgg_get_site_url() . "groups/requests/{$page_owner->getGUID()}";
            elgg_register_menu_item('page', array(
                'name' => 'membership_requests',
                'text' => elgg_echo('groups:membershiprequests'),
                'href' => $url,
            ));
        }
    }
    if (elgg_get_context() == 'groups' && !elgg_instanceof($page_owner, 'group')) {
        elgg_register_menu_item('page', array(
            'name' => 'groups:all',
            'text' => elgg_echo('groups:all'),
            'href' => 'groups/all',
        ));

        $user = elgg_get_logged_in_user_entity();
        if ($user) {
            $url = "groups/owner/$user->username";
            $item = new ElggMenuItem('groups:owned', elgg_echo('groups:owned'), $url);
            elgg_register_menu_item('page', $item);
            $url = "groups/member/$user->username";
            $item = new ElggMenuItem('groups:member', elgg_echo('groups:yours'), $url);
            elgg_register_menu_item('page', $item);
            $url = "groups/invitations/$user->username";
            $item = new ElggMenuItem('groups:user:invites', elgg_echo('groups:invitations'), $url);
            elgg_register_menu_item('page', $item);
        }
        $user = elgg_get_logged_in_user_entity();
        if ($user->usertype == "Teacher") {

            $teacher = $user->username;
            elgg_register_menu_item('page', array(
                'name' => 'subject_teacher',
                'text' => 'Môn học tôi phụ trách',
                'href' => 'submana/subjects/' . $teacher,
            ));

            elgg_register_menu_item('page', array(
                'name' => 'project_teacher',
                'text' => 'Nhóm do tôi hướng dẫn',
                'href' => 'groups/all?filter=project_teacher',
            ));

            elgg_register_menu_item('page', array(
                'name' => 'project_teacher',
                'text' => 'Các đánh giá của tôi',
                'href' => 'groups/all?filter=review_teacher_make',
            ));
        }
    }
}

/**
 * Groups page handler
 *
 * URLs take the form of
 *  All groups:           groups/all
 *  User's owned groups:  groups/owner/<username>
 *  User's member groups: groups/member/<username>
 *  Group profile:        groups/profile/<guid>/<title>
 *  New group:            groups/add/<guid>
 *  Edit group:           groups/edit/<guid>
 *  Group invitations:    groups/invitations/<username>
 *  Invite to group:      groups/invite/<guid>
 *  Membership requests:  groups/requests/<guid>
 *  Group activity:       groups/activity/<guid>
 *  Group members:        groups/members/<guid>
 *  Review                  groups/review/<guid>
 *  SVN activity  		  groups/svn/<guid>
 *
 * @param array $page Array of url segments for routing
 * @return bool
 */
function groups_page_handler($page)
{

    elgg_load_library('elgg:groups');

    switch ($page[0]) {
        case 'all':
            elgg_push_breadcrumb(elgg_echo('groups'), "groups/all");
            groups_handle_all_page();
            break;
        case 'search':
            elgg_push_breadcrumb(elgg_echo('groups'), "groups/all");
            groups_search_page();
            break;
        case 'owner':
            elgg_push_breadcrumb(elgg_echo('groups'), "groups/all");
            groups_handle_owned_page();
            break;
        case 'member':
            elgg_push_breadcrumb(elgg_echo('groups'), "groups/all");
            set_input('username', $page[1]);
            groups_handle_mine_page();
            break;
        case 'invitations':
            elgg_push_breadcrumb(elgg_echo('groups'), "groups/all");
            set_input('username', $page[1]);
            groups_handle_invitations_page();
            break;
        case 'add':
            elgg_push_breadcrumb(elgg_echo('groups'), "groups/all");
            groups_handle_edit_page('add');
            break;
        case 'addgroupsubject':
            elgg_push_breadcrumb(elgg_echo('groups'), "groups/all");
            groups_handle_edit_page('addgroupsubject');
            break;
        case 'edit':
            elgg_push_breadcrumb(elgg_echo('groups'), "groups/all");
            groups_handle_edit_page('edit', $page[1]);
            break;
        case 'profile':
            groups_handle_profile_page($page[1]);
            break;
        case 'activity':
            elgg_push_breadcrumb(elgg_echo('groups'), "groups/all");
            groups_handle_activity_page($page[1]);
            break;
        case 'members':
            elgg_push_breadcrumb(elgg_echo('groups'), "groups/all");
            groups_handle_members_page($page[1]);
            break;
        case 'invite':
            elgg_push_breadcrumb(elgg_echo('groups'), "groups/all");
            groups_handle_invite_page($page[1]);
            break;
        case 'requests':
            elgg_push_breadcrumb(elgg_echo('groups'), "groups/all");
            groups_handle_requests_page($page[1]);
            break;
        case 'review':
            elgg_push_breadcrumb(elgg_echo('groups'), "groups/all");
            groups_handle_review_page($page[1]);
            break;
        case 'mark':
            elgg_push_breadcrumb(elgg_echo('groups'), "groups/all");
            groups_handle_mark_page($page[1]);
            break;
        case 'svn':
        	elgg_push_breadcrumb(elgg_echo('groups'), "groups/all");
            groups_handle_svn_page($page[1]);
            break;
        default:
            return false;
    }
    return true;
}

/**
 * Handle group icons.
 *
 * @param array $page
 * @return void
 */
function groups_icon_handler($page)
{

    // The username should be the file we're getting
    if (isset($page[0])) {
        set_input('group_guid', $page[0]);
    }
    if (isset($page[1])) {
        set_input('size', $page[1]);
    }
    // Include the standard profile index
    $plugin_dir = elgg_get_plugins_path();
    include("$plugin_dir/groups/icon.php");
    return true;
}

/**
 * Populates the ->getUrl() method for group objects
 *
 * @param ElggEntity $entity File entity
 * @return string File URL
 */
function groups_url($entity)
{
    $title = elgg_get_friendly_title($entity->name);

    return "groups/profile/{$entity->guid}/$title";
}

/**
 * Override the default entity icon for groups
 *
 * @return string Relative URL
 */
function groups_icon_url_override($hook, $type, $returnvalue, $params)
{
    /* @var ElggGroup $group */
    $group = $params['entity'];
    $size = $params['size'];

    $icontime = $group->icontime;
    // handle missing metadata (pre 1.7 installations)
    if (null === $icontime) {
        $file = new ElggFile();
        $file->owner_guid = $group->owner_guid;
        $file->setFilename("groups/" . $group->guid . "large.jpg");
        $icontime = $file->exists() ? time() : 0;
        create_metadata($group->guid, 'icontime', $icontime, 'integer', $group->owner_guid, ACCESS_PUBLIC);
    }
    if ($icontime) {
        // return thumbnail
        return "groupicon/$group->guid/$size/$icontime.jpg";
    }

    return "mod/groups/graphics/default{$size}.gif";
}

/**
 * Add owner block link
 */
function groups_activity_owner_block_menu($hook, $type, $return, $params)
{
    if (elgg_instanceof($params['entity'], 'group')) {
        if ($params['entity']->activity_enable != "no") {
            $url = "groups/activity/{$params['entity']->guid}";
            $item = new ElggMenuItem('activity', elgg_echo('groups:activity'), $url);
            $return[] = $item;
        }
    }

    return $return;
}

/**
 * Add links/info to entity menu particular to group entities
 */
function groups_entity_menu_setup($hook, $type, $return, $params)
{
    if (elgg_in_context('widgets')) {
        return $return;
    }

    $entity = $params['entity'];
    $handler = elgg_extract('handler', $params, false);
    if ($handler != 'groups') {
        return $return;
    }

    foreach ($return as $index => $item) {
        if (in_array($item->getName(), array('access', 'likes', 'edit', 'delete'))) {
            unset($return[$index]);
        }
    }

    // membership type
    $membership = $entity->membership;
    if ($membership == ACCESS_PUBLIC) {
        $mem = elgg_echo("groups:open");
    } else {
        $mem = elgg_echo("groups:closed");
    }
    $options = array(
        'name' => 'membership',
        'text' => $mem,
        'href' => false,
        'priority' => 100,
    );
    $return[] = ElggMenuItem::factory($options);

    // number of members
    $num_members = get_group_members($entity->guid, 10, 0, 0, true);
    $members_string = elgg_echo('groups:member');
    $options = array(
        'name' => 'members',
        'text' => $num_members . ' ' . $members_string,
        'href' => false,
        'priority' => 200,
    );
    $return[] = ElggMenuItem::factory($options);

    // feature link
    if (elgg_is_admin_logged_in()) {
        $isFeatured = $entity->featured_group == "yes";

        $return[] = ElggMenuItem::factory(array(
            'name' => 'feature',
            'text' => elgg_echo("groups:makefeatured"),
            'href' => elgg_add_action_tokens_to_url("action/groups/featured?group_guid={$entity->guid}&action_type=feature"),
            'priority' => 300,
            'item_class' => $isFeatured ? 'hidden' : '',
        ));

        $return[] = ElggMenuItem::factory(array(
            'name' => 'unfeature',
            'text' => elgg_echo("groups:makeunfeatured"),
            'href' => elgg_add_action_tokens_to_url("action/groups/featured?group_guid={$entity->guid}&action_type=unfeature"),
            'priority' => 300,
            'item_class' => $isFeatured ? '' : 'hidden',
        ));
    }

    return $return;
}

/**
 * Add a remove user link to user hover menu when the page owner is a group
 */
function groups_user_entity_menu_setup($hook, $type, $return, $params)
{
    if (elgg_is_logged_in()) {
        $group = elgg_get_page_owner_entity();

        // Check for valid group
        if (!elgg_instanceof($group, 'group')) {
            return $return;
        }

        $entity = $params['entity'];

        // Make sure we have a user and that user is a member of the group
        if (!elgg_instanceof($entity, 'user') || !$group->isMember($entity)) {
            return $return;
        }

        // Add remove link if we can edit the group, and if we're not trying to remove the group owner
        if ($group->canEdit() && $group->getOwnerGUID() != $entity->guid) {
            $remove = elgg_view('output/confirmlink', array(
                'href' => "action/groups/remove?user_guid={$entity->guid}&group_guid={$group->guid}",
                'text' => elgg_echo('groups:removeuser'),
            ));

            $options = array(
                'name' => 'removeuser',
                'text' => $remove,
                'priority' => 999,
            );
            $return[] = ElggMenuItem::factory($options);
        }
    }

    return $return;
}

/**
 * Add edit and delete links for forum replies
 */
function groups_annotation_menu_setup($hook, $type, $return, $params)
{
    if (elgg_in_context('widgets')) {
        return $return;
    }

    $annotation = $params['annotation'];

    if ($annotation->name != 'group_topic_post') {
        return $return;
    }

    if ($annotation->canEdit()) {
        $url = elgg_http_add_url_query_elements('action/discussion/reply/delete', array(
            'annotation_id' => $annotation->id,
        ));

        $options = array(
            'name' => 'delete',
            'href' => $url,
            'text' => "<span class=\"elgg-icon elgg-icon-delete\"></span>",
            'confirm' => elgg_echo('deleteconfirm'),
            'encode_text' => false
        );
        $return[] = ElggMenuItem::factory($options);

        $url = elgg_http_add_url_query_elements('discussion', array(
            'annotation_id' => $annotation->id,
        ));

        $options = array(
            'name' => 'edit',
            'href' => "#edit-annotation-$annotation->id",
            'text' => elgg_echo('edit'),
            'encode_text' => false,
            'rel' => 'toggle',
        );
        $return[] = ElggMenuItem::factory($options);
    }

    return $return;
}

/**
 * Groups created so create an access list for it
 */
function groups_create_event_listener($event, $object_type, $object)
{
    $ac_name = elgg_echo('groups:group') . ": " . $object->name;
    $group_id = create_access_collection($ac_name, $object->guid);
    if ($group_id) {
        $object->group_acl = $group_id;
    } else {
        // delete group if access creation fails
        return false;
    }

    return true;
}

/**
 * Hook to listen to read access control requests and return all the groups you are a member of.
 */
function groups_read_acl_plugin_hook($hook, $entity_type, $returnvalue, $params)
{
    //error_log("READ: " . var_export($returnvalue));
    $user = elgg_get_logged_in_user_entity();
    if ($user) {
        // Not using this because of recursion.
        // Joining a group automatically add user to ACL,
        // So just see if they're a member of the ACL.
        //$membership = get_users_membership($user->guid);

        $members = get_members_of_access_collection($group->group_acl);
        print_r($members);
        exit;

        if ($membership) {
            foreach ($membership as $group)
                $returnvalue[$user->guid][$group->group_acl] = elgg_echo('groups:group') . ": " . $group->name;
            return $returnvalue;
        }
    }
}

/**
 * Return the write access for the current group if the user has write access to it.
 */
function groups_write_acl_plugin_hook($hook, $entity_type, $returnvalue, $params)
{
    $page_owner = elgg_get_page_owner_entity();
    $user_guid = $params['user_id'];
    $user = get_entity($user_guid);
    if (!$user) {
        return $returnvalue;
    }

    // only insert group access for current group
    if ($page_owner instanceof ElggGroup) {
        if ($page_owner->canWriteToContainer($user_guid)) {
            $returnvalue[$page_owner->group_acl] = elgg_echo('groups:group') . ': ' . $page_owner->name;

            unset($returnvalue[ACCESS_FRIENDS]);
        }
    } else {
        // if the user owns the group, remove all access collections manually
        // this won't be a problem once the group itself owns the acl.
        $groups = elgg_get_entities_from_relationship(array(
            'relationship' => 'member',
            'relationship_guid' => $user_guid,
            'inverse_relationship' => FALSE,
            'limit' => 999
        ));

        if ($groups) {
            foreach ($groups as $group) {
                unset($returnvalue[$group->group_acl]);
            }
        }
    }

    return $returnvalue;
}

/**
 * Groups deleted, so remove access lists.
 */
function groups_delete_event_listener($event, $object_type, $object)
{
    delete_access_collection($object->group_acl);

    return true;
}

/**
 * Listens to a group join event and adds a user to the group's access control
 *
 */
function groups_user_join_event_listener($event, $object_type, $object)
{

    $group = $object['group'];
    $user = $object['user'];
    $acl = $group->group_acl;

    add_user_to_access_collection($user->guid, $acl);

    return true;
}

/**
 * Make sure users are added to the access collection
 */
function groups_access_collection_override($hook, $entity_type, $returnvalue, $params)
{
    if (isset($params['collection'])) {
        if (elgg_instanceof(get_entity($params['collection']->owner_guid), 'group')) {
            return true;
        }
    }
}

/**
 * Listens to a group leave event and removes a user from the group's access control
 *
 */
function groups_user_leave_event_listener($event, $object_type, $object)
{

    $group = $object['group'];
    $user = $object['user'];
    $acl = $group->group_acl;

    remove_user_from_access_collection($user->guid, $acl);

    return true;
}

/**
 * Grabs groups by invitations
 * Have to override all access until there's a way override access to getter functions.
 *
 * @param int $user_guid The user's guid
 * @param bool $return_guids Return guids rather than ElggGroup objects
 *
 * @return array ElggGroups or guids depending on $return_guids
 */
function groups_get_invited_groups($user_guid, $return_guids = FALSE)
{
    $ia = elgg_set_ignore_access(TRUE);
    $groups = elgg_get_entities_from_relationship(array(
        'relationship' => 'invited',
        'relationship_guid' => $user_guid,
        'inverse_relationship' => TRUE,
        'limit' => 0,
    ));
    elgg_set_ignore_access($ia);

    if ($return_guids) {
        $guids = array();
        foreach ($groups as $group) {
            $guids[] = $group->getGUID();
        }

        return $guids;
    }

    return $groups;
}

/**
 * Join a user to a group, add river event, clean-up invitations
 *
 * @param ElggGroup $group
 * @param ElggUser $user
 * @return bool
 */
function groups_join_group($group, $user)
{

    // access ignore so user can be added to access collection of invisible group
    $ia = elgg_set_ignore_access(TRUE);
    $result = $group->join($user);
    elgg_set_ignore_access($ia);

    if ($result) {
        // flush user's access info so the collection is added
        get_access_list($user->guid, 0, true);

        // Remove any invite or join request flags
        remove_entity_relationship($group->guid, 'invited', $user->guid);
        remove_entity_relationship($user->guid, 'membership_request', $group->guid);

        add_to_river('river/relationship/member/create', 'join', $user->guid, $group->guid);

        return true;
    }

    return false;
}

/**
 * Function to use on groups for access. It will house private, loggedin, public,
 * and the group itself. This is when you don't want other groups or access lists
 * in the access options available.
 *
 * @return array
 */
function group_access_options($group)
{
    $access_array = array(
        ACCESS_PRIVATE => 'private',
        ACCESS_LOGGED_IN => 'logged in users',
        ACCESS_PUBLIC => 'public',
        $group->group_acl => elgg_echo('groups:acl', array($group->name)),
    );
    return $access_array;
}

function activity_profile_menu($hook, $entity_type, $return_value, $params)
{

    if ($params['owner'] instanceof ElggGroup) {
        $return_value[] = array(
            'text' => elgg_echo('Activity'),
            'href' => "groups/activity/{$params['owner']->getGUID()}"
        );
    }
    return $return_value;
}

/**
 * Parse ECML on group discussion views
 */
function groups_ecml_views_hook($hook, $entity_type, $return_value, $params)
{
    $return_value['forum/viewposts'] = elgg_echo('groups:ecml:discussion');

    return $return_value;
}

/**
 * Parse ECML on group profiles
 */
function groupprofile_ecml_views_hook($hook, $entity_type, $return_value, $params)
{
    $return_value['groups/groupprofile'] = elgg_echo('groups:ecml:groupprofile');

    return $return_value;
}


/**
 * Discussion
 *
 */

elgg_register_event_handler('init', 'system', 'discussion_init');

/**
 * Initialize the discussion component
 */
function discussion_init()
{

    elgg_register_library('elgg:discussion', elgg_get_plugins_path() . 'groups/lib/discussion.php');

    elgg_register_page_handler('discussion', 'discussion_page_handler');
    elgg_register_page_handler('forum', 'discussion_forum_page_handler');

    elgg_register_entity_url_handler('object', 'groupforumtopic', 'discussion_override_topic_url');

    // commenting not allowed on discussion topics (use a different annotation)
    elgg_register_plugin_hook_handler('permissions_check:comment', 'object', 'discussion_comment_override');

    $action_base = elgg_get_plugins_path() . 'groups/actions/discussion';
    elgg_register_action('discussion/save', "$action_base/save.php");
    elgg_register_action('discussion/delete', "$action_base/delete.php");
    elgg_register_action('discussion/reply/save', "$action_base/reply/save.php");
    elgg_register_action('discussion/reply/delete', "$action_base/reply/delete.php");

    // add link to owner block
    elgg_register_plugin_hook_handler('register', 'menu:owner_block', 'discussion_owner_block_menu');

    // Register for search.
    elgg_register_entity_type('object', 'groupforumtopic');
    elgg_register_entity_type('object', 'review');

    // because replies are not comments, need of our menu item
    elgg_register_plugin_hook_handler('register', 'menu:river', 'discussion_add_to_river_menu');

    // add the forum tool option
    add_group_tool_option('forum', elgg_echo('groups:enableforum'), true);
    elgg_extend_view('groups/tool_latest', 'discussion/group_module');

    // notifications
    register_notification_object('object', 'groupforumtopic', elgg_echo('discussion:notification:topic:subject'));
    elgg_register_plugin_hook_handler('notify:entity:message', 'object', 'groupforumtopic_notify_message');
    elgg_register_event_handler('create', 'annotation', 'discussion_reply_notifications');
    elgg_register_plugin_hook_handler('notify:annotation:message', 'group_topic_post', 'discussion_create_reply_notification');
}

/**
 * Exists for backwards compatibility for Elgg 1.7
 */
function discussion_forum_page_handler($page)
{
    switch ($page[0]) {
        case 'topic':
            header('Status: 301 Moved Permanently');
            forward("/discussion/view/{$page[1]}/{$page[2]}");
            break;
        default:
            return false;
    }
}

/**
 * Discussion page handler
 *
 * URLs take the form of
 *  All topics in site:    discussion/all
 *  List topics in forum:  discussion/owner/<guid>
 *  View discussion topic: discussion/view/<guid>
 *  Add discussion topic:  discussion/add/<guid>
 *  Edit discussion topic: discussion/edit/<guid>
 *
 * @param array $page Array of url segments for routing
 * @return bool
 */
function discussion_page_handler($page)
{

    elgg_load_library('elgg:discussion');

    elgg_push_breadcrumb(elgg_echo('discussion'), 'discussion/all');

    switch ($page[0]) {
        case 'all':
            discussion_handle_all_page();
            break;
        case 'owner':
            discussion_handle_list_page($page[1]);
            break;
        case 'add':
            discussion_handle_edit_page('add', $page[1]);
            break;
        case 'edit':
            discussion_handle_edit_page('edit', $page[1]);
            break;
        case 'view':
            discussion_handle_view_page($page[1]);
            break;
        default:
            return false;
    }
    return true;
}

/**
 * Override the discussion topic url
 *
 * @param ElggObject $entity Discussion topic
 * @return string
 */
function discussion_override_topic_url($entity)
{
    return 'discussion/view/' . $entity->guid . '/' . elgg_get_friendly_title($entity->title);
}

/**
 * We don't want people commenting on topics in the river
 */
function discussion_comment_override($hook, $type, $return, $params)
{
    if (elgg_instanceof($params['entity'], 'object', 'groupforumtopic')) {
        return false;
    }
}

/**
 * Add owner block link
 */
function discussion_owner_block_menu($hook, $type, $return, $params)
{
    if (elgg_instanceof($params['entity'], 'group')) {
        if ($params['entity']->forum_enable != "no") {
            $url = "discussion/owner/{$params['entity']->guid}";
            $item = new ElggMenuItem('discussion', elgg_echo('discussion:group'), $url);
            $return[] = $item;
        }
    }

    return $return;
}

/**
 * Add the reply button for the river
 */
function discussion_add_to_river_menu($hook, $type, $return, $params)
{
    if (elgg_is_logged_in() && !elgg_in_context('widgets')) {
        $item = $params['item'];
        $object = $item->getObjectEntity();
        if (elgg_instanceof($object, 'object', 'groupforumtopic')) {
            if ($item->annotation_id == 0) {
                $group = $object->getContainerEntity();
                if ($group && ($group->canWriteToContainer() || elgg_is_admin_logged_in())) {
                    $options = array(
                        'name' => 'reply',
                        'href' => "#groups-reply-$object->guid",
                        'text' => elgg_view_icon('speech-bubble'),
                        'title' => elgg_echo('reply:this'),
                        'rel' => 'toggle',
                        'priority' => 50,
                    );
                    $return[] = ElggMenuItem::factory($options);
                }
            }
        }
    }

    return $return;
}

/**
 * Create discussion notification body
 *
 * @todo namespace method with 'discussion'
 *
 * @param string $hook
 * @param string $type
 * @param string $message
 * @param array $params
 */
function groupforumtopic_notify_message($hook, $type, $message, $params)
{
    $entity = $params['entity'];
    $to_entity = $params['to_entity'];
    $method = $params['method'];

    if (($entity instanceof ElggEntity) && ($entity->getSubtype() == 'groupforumtopic')) {
        $descr = $entity->description;
        $title = $entity->title;
        $url = $entity->getURL();
        $owner = $entity->getOwnerEntity();
        $group = $entity->getContainerEntity();

        return elgg_echo('groups:notification', array(
            $owner->name,
            $group->name,
            $entity->title,
            $entity->description,
            $entity->getURL()
        ));
    }

    return null;
}

/**
 * Create discussion reply notification body
 *
 * @param string $hook
 * @param string $type
 * @param string $message
 * @param array $params
 */
function discussion_create_reply_notification($hook, $type, $message, $params)
{
    $reply = $params['annotation'];
    $method = $params['method'];
    $topic = $reply->getEntity();
    $poster = $reply->getOwnerEntity();
    $group = $topic->getContainerEntity();

    return elgg_echo('discussion:notification:reply:body', array(
        $poster->name,
        $topic->title,
        $group->name,
        $reply->value,
        $topic->getURL(),
    ));
}

/**
 * Catch reply to discussion topic and generate notifications
 *
 * @todo this will be replaced in Elgg 1.9 and is a clone of object_notifications()
 *
 * @param string $event
 * @param string $type
 * @param ElggAnnotation $annotation
 * @return void
 */
function discussion_reply_notifications($event, $type, $annotation)
{
    global $CONFIG, $NOTIFICATION_HANDLERS;

    if ($annotation->name !== 'group_topic_post') {
        return;
    }

    // Have we registered notifications for this type of entity?
    $object_type = 'object';
    $object_subtype = 'groupforumtopic';

    $topic = $annotation->getEntity();
    if (!$topic) {
        return;
    }

    $poster = $annotation->getOwnerEntity();
    if (!$poster) {
        return;
    }

    if (isset($CONFIG->register_objects[$object_type][$object_subtype])) {
        $subject = $CONFIG->register_objects[$object_type][$object_subtype];
        $string = $subject . ": " . $topic->getURL();

        // Get users interested in content from this person and notify them
        // (Person defined by container_guid so we can also subscribe to groups if we want)
        foreach ($NOTIFICATION_HANDLERS as $method => $foo) {
            $interested_users = elgg_get_entities_from_relationship(array(
                'relationship' => 'notify' . $method,
                'relationship_guid' => $topic->getContainerGUID(),
                'inverse_relationship' => true,
                'types' => 'user',
                'limit' => 0,
            ));

            if ($interested_users && is_array($interested_users)) {
                foreach ($interested_users as $user) {
                    if ($user instanceof ElggUser && !$user->isBanned()) {
                        if (($user->guid != $poster->guid) && has_access_to_entity($topic, $user) && $topic->access_id != ACCESS_PRIVATE) {
                            $body = elgg_trigger_plugin_hook('notify:annotation:message', $annotation->getSubtype(), array(
                                'annotation' => $annotation,
                                'to_entity' => $user,
                                'method' => $method), $string);
                            if (empty($body) && $body !== false) {
                                $body = $string;
                            }
                            if ($body !== false) {
                                notify_user($user->guid, $topic->getContainerGUID(), $subject, $body, null, array($method));
                            }
                        }
                    }
                }
            }
        }
    }
}

/**
 * A simple function to see who can edit a group discussion post
 * @param the comment $entity
 * @param user who owns the group $group_owner
 * @return boolean
 */
function groups_can_edit_discussion($entity, $group_owner)
{

    //logged in user
    $user = elgg_get_logged_in_user_guid();

    if (($entity->owner_guid == $user) || $group_owner == $user || elgg_is_admin_logged_in()) {
        return true;
    } else {
        return false;
    }
}

/**
 * Process upgrades for the groups plugin
 */
function groups_run_upgrades()
{
    $path = elgg_get_plugins_path() . 'groups/upgrades/';
    $files = elgg_get_upgrade_files($path);
    foreach ($files as $file) {
        include "$path{$file}";
    }
}
